/**
 * 
 */
package com.solome.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

/**
 * 支持GZIP压缩协议的可缓冲对象
 * 
 * @author soells
 * 
 */
public class ZipCacheObject {

	private byte[] _object;// 转换后的压缩对象

	/**
	 * 
	 * @param _object
	 */
	public ZipCacheObject(byte[] _object) {
		this._object = _object;
	}

	/**
	 * 
	 * @param target
	 */
	public ZipCacheObject(Object target) {
		this.setObject(target);
	}

	/**
	 * 进入压缩操作
	 * 
	 * @param dataSrc
	 *            原始数据
	 * @return 压缩后的数据
	 */
	private byte[] compress(byte[] dataSrc) {
		ByteArrayOutputStream baos = null;
		GZIPOutputStream gzout = null;
		try {
			baos = new ByteArrayOutputStream();
			gzout = new GZIPOutputStream(baos);
			gzout.write(dataSrc);
			gzout.finish();
			gzout.flush();
			baos.flush();
			return baos.toByteArray();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (gzout != null)
					gzout.close();
				if (baos != null)
					baos.close();
			} catch (Exception e) {
			}
		}
		return null;
	}

	/**
	 * 
	 * @param dataSrc
	 * @return
	 */
	private byte[] extract(byte[] dataSrc) {
		ByteArrayInputStream bais = null;
		GZIPInputStream gzin = null;
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		try {
			bais = new ByteArrayInputStream(dataSrc);
			gzin = new GZIPInputStream(bais);
			byte[] buf = new byte[1024];
			int len;
			while ((len = gzin.read(buf)) > 0) {
				baos.write(buf, 0, len);
			}
			baos.flush();
			return baos.toByteArray();
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			try {
				baos.close();
				gzin.close();
				bais.close();
			} catch (Exception ex) {
			}
		}
		return null;
	}

	/**
	 * 根据字节数据来还原角色对象
	 * 
	 * @param data
	 *            数据来源
	 * @return 还原后的角色对象
	 */
	public Object getObject() {
		ByteArrayInputStream bais = null;
		ObjectInputStream dis = null;
		try {
			byte[] src = extract(_object);
			bais = new ByteArrayInputStream(src);
			dis = new ObjectInputStream(bais);
			Object tmp = dis.readObject();
			return (Object) tmp;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				dis.close();
				bais.close();
			} catch (Exception ex) {
			}
		}
		return null;
	}

	/**
	 * 
	 * @return
	 */
	public byte[] getObjectArray() {
		return _object;
	}

	/**
	 * 将角色数据打包成字节数据
	 * 
	 * @param player
	 *            来源角色
	 * @return 打包后的数据
	 */
	public void setObject(Object target) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ObjectOutputStream dos = null;
		try {
			dos = new ObjectOutputStream(baos);
			dos.writeObject(target);
			dos.flush();
			baos.flush();
			byte[] src = baos.toByteArray();
			_object = this.compress(src);

			System.err.println(target.getClass() + "(HASH=" + target.hashCode()
					+ ") srcObjectSize=" + src.length + "..conObjectSize="
					+ _object.length);
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			try {
				dos.close();
				baos.close();
			} catch (Exception ex) {
			}
		}
	}

}
